package com.sf.fy.uav.withdrawal.service.impl;

import cn.hutool.core.util.DesensitizedUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sf.fy.uav.common.enums.ScenicSpotStatusEnum;
import com.sf.fy.uav.common.request.operate.ScenicSpotReq;
import com.sf.fy.uav.common.response.operational.ScenicSpotRes;
import com.sf.fy.uav.common.utils.BeanUtil;
import com.sf.fy.uav.common.utils.PhoneEncoderUtil;
import com.sf.fy.uav.common.utils.RespJsonPageData;
import com.sf.fy.uav.common.utils.Rs;
import com.sf.fy.uav.withdrawal.entity.ScenicSpot;
import com.sf.fy.uav.withdrawal.mapper.ScenicSpotMapper;
import com.sf.fy.uav.withdrawal.service.IScenicSpotService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author LTQ
 * @since 2023-12-07
 */
@Service
@RequiredArgsConstructor
public class ScenicSpotServiceImpl extends ServiceImpl<ScenicSpotMapper, ScenicSpot> implements IScenicSpotService {
   private final ScenicSpotMapper scenicSpotMapper;

   private final PhoneEncoderUtil phoneEncoderUtil;

   private static final String LONGITUDE_AND_LATITUDE = "^[0-9]+(.[0-9]{1,8})?$";
   private static final Integer CONST_NUM = 0;
   private static final Integer PHONE_CHECK = 11;
   private static final Integer NAME_CHECK = 15;
   private static final Integer ADDRESS_CHECK = 80;

    @Override
    public RespJsonPageData<ScenicSpotRes> getPageScenicSpot(ScenicSpotReq scenicSpotReq) {
        LambdaQueryWrapper<ScenicSpot> wrapper = Wrappers.lambdaQuery();
        wrapper.like(StringUtils.isNotBlank(scenicSpotReq.getName()) ,ScenicSpot::getName,scenicSpotReq.getName())
                .eq(!ObjectUtils.isEmpty(scenicSpotReq.getStatus()),ScenicSpot::getStatus,scenicSpotReq.getStatus())
                .eq(ScenicSpot::getDeleted,false)
                .orderByDesc(ScenicSpot::getCreateTime);
        Page<ScenicSpot> scenicSpotPageList = scenicSpotMapper.selectPage(new Page<>(scenicSpotReq.getPage(), scenicSpotReq.getSize()),wrapper);
        List<ScenicSpotRes> scenicSpotResList = BeanUtil.copyProperties(scenicSpotPageList.getRecords(), ScenicSpotRes.class);
        if(!CollectionUtils.isEmpty(scenicSpotResList)){
            scenicSpotResList.forEach(scenicSpotRes ->{
                scenicSpotRes.setStatusName(ScenicSpotStatusEnum.getDesc(scenicSpotRes.getStatus()));
                scenicSpotRes.setPhone(DesensitizedUtil.desensitized(phoneEncoderUtil.decryptString(scenicSpotRes.getPhone()), DesensitizedUtil.DesensitizedType.MOBILE_PHONE));
                scenicSpotRes.setIntegrityAddress(scenicSpotRes.getProvince()+scenicSpotRes.getCity()+scenicSpotRes.getDistrict()+scenicSpotRes.getAddress());
            });
        }
        return RespJsonPageData.success(scenicSpotResList,scenicSpotPageList.getTotal());
    }

    @Override
    public ScenicSpot selectById(String id) {
        QueryWrapper<ScenicSpot> scenicSpotQueryWrapper = new QueryWrapper<>();
        scenicSpotQueryWrapper.eq("id", id);
        scenicSpotQueryWrapper.eq("status", ScenicSpotStatusEnum.NORMAL.getValue());
        scenicSpotQueryWrapper.eq("deleted", false);
        return scenicSpotMapper.selectOne(scenicSpotQueryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Rs<Integer> save(ScenicSpotReq scenicSpotReq) {
        batchVoidAnce(scenicSpotReq);
        Date date = new Date();
        ScenicSpot scenicSpot = BeanUtil.copyProperties(scenicSpotReq, ScenicSpot.class);
        scenicSpot.setCreateTime(date);
        scenicSpot.setUpdateTime(date);
        scenicSpot.setDeleted(false);
        scenicSpot.setPhone(phoneEncoderUtil.encryptString(scenicSpotReq.getPhone()));
        int con = scenicSpotMapper.insert(scenicSpot);
        if(con>CONST_NUM){
            return Rs.success(CONST_NUM);
        }else {
            return Rs.failed();
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Rs<Integer> updateById(ScenicSpotReq scenicSpotReq) {
        if(StringUtils.isBlank(scenicSpotReq.getId())){
            throw new RuntimeException("景区id不能为空");
        }
        batchVoidAnce(scenicSpotReq);
        ScenicSpot scenicSpot = BeanUtil.copyProperties(scenicSpotReq, ScenicSpot.class);
        scenicSpot.setPhone(phoneEncoderUtil.encryptString(scenicSpotReq.getPhone()));
        scenicSpot.setUpdateTime(new Date());
        int updateCum = scenicSpotMapper.updateById(scenicSpot);
        if(updateCum>CONST_NUM){
            return Rs.success(CONST_NUM);
        }else {
            return Rs.failed();
        }
    }

    private void batchVoidAnce(ScenicSpotReq scenicSpotReq){
        if(StringUtils.isBlank(scenicSpotReq.getName())){
            throw new RuntimeException("景区名称不能为空");
        }
        if(scenicSpotReq.getName().length()>NAME_CHECK){
            throw new RuntimeException("景区名称长度不能超过15位");
        }
        if(StringUtils.isBlank(scenicSpotReq.getProvinceCode())){
            throw new RuntimeException("省编号不能为空");
        }
        if(StringUtils.isBlank(scenicSpotReq.getProvince())){
            throw new RuntimeException("省名不能为空");
        }
        if(StringUtils.isBlank(scenicSpotReq.getCityCode())){
            throw new RuntimeException("市编号不能为空");
        }
        if(StringUtils.isBlank(scenicSpotReq.getCity())){
            throw new RuntimeException("市名不能为空");
        }
        if(StringUtils.isBlank(scenicSpotReq.getDistrictCode())){
            throw new RuntimeException("区编号不能为空");
        }
        if(StringUtils.isBlank(scenicSpotReq.getDistrict())){
            throw new RuntimeException("区名不能为空");
        }
        if(StringUtils.isBlank(scenicSpotReq.getAddress())){
            throw new RuntimeException("详细地址不能为空");
        }
        if(scenicSpotReq.getAddress().length()>ADDRESS_CHECK){
            throw new RuntimeException("详细地址长度不能超过80个字符");
        }
        if(ObjectUtils.isEmpty(scenicSpotReq.getLongitude())||scenicSpotReq.getLongitude().compareTo(BigDecimal.ZERO)<=CONST_NUM){
            throw new RuntimeException("经度不能为空,不能为零或负数");
        }
        if(ObjectUtils.isEmpty(scenicSpotReq.getLatitude())||scenicSpotReq.getLatitude().compareTo(BigDecimal.ZERO)<=CONST_NUM){
            throw new RuntimeException("纬度不能为空,不能为零或负数");
        }
        if(!scenicSpotReq.getLongitude().toString().matches(LONGITUDE_AND_LATITUDE)){
            throw new RuntimeException("经度只能只正数或者最大8位小数");
        }
        if(!scenicSpotReq.getLatitude().toString().matches(LONGITUDE_AND_LATITUDE)){
            throw new RuntimeException("纬度只能只正数或者最大8位小数");
        }
        if(StringUtils.isBlank(scenicSpotReq.getContacts())){
            throw new RuntimeException("联系人不能为空");
        }
        if(scenicSpotReq.getContacts().length()>NAME_CHECK){
            throw new RuntimeException("联系人姓名不能超过15个字符");
        }
        if(StringUtils.isBlank(scenicSpotReq.getPhone())){
            throw new RuntimeException("手机号不能为空");
        }
        if(scenicSpotReq.getPhone().length()>PHONE_CHECK){
            throw new RuntimeException("手机号长度不能超过11位");
        }
        if(ObjectUtils.isEmpty(scenicSpotReq.getStatus())){
            throw new RuntimeException("状态不能为空");
        }
        if(StringUtils.isBlank(scenicSpotReq.getProcessedBy())){
            throw new RuntimeException("处理人不能为空");
        }
    }
}
